#include <iostream>
#define MAX_V 100
using namespace std;

class Node{
public:
	int index;  //顶点编号
	int dist;   //到源点的长度
	Node* next; //链表的下一个节点

	Node(int index = 0):index(index){
		this->dist = 0xFFFFFFF;
		this->next = 0;
	}
};

/*优先队列*/
class List{
public:
	Node* head;

	List(){
		head = new Node();
	}

	~List(){
		delete head;
	}

	void add(Node* node){
		for(Node* i = head; i != 0; i = i->next){
			if(i->next == 0 ||  node->dist < i->next->dist){
				node->next = i->next;
				i->next = node;
				break;
			}
		}
	}

	Node* removeFirst(){
		if(!empty()){
			Node* temp = head->next;
			head->next = head->next->next;
			return temp;
		}
		return 0;
	}

	bool exists(Node* node){
		for(Node* i = head->next; i != 0; i = i->next){
			if(i == node){
				return true;
			}
		}
		return false;
	}

	bool empty(){
		return head->next == 0;
	}
};

/* 单源最短路径-使用分支限界法
 * map : 有向图邻接矩阵
 * n   : 顶点个数
 * s   : 源点下标
 * d   : 目的点下标
 *   返回值: 源点到目的点的最知路长度
 * */

int Dijkstra(int map[MAX_V][MAX_V], int n, int s, int d){

	//初始化结构
	List opened;
	List closed;
	Node** nodes = new Node*[n];
	for(int i = 0; i < n; i++){
		nodes[i] = new Node(i);
	}

	nodes[s]->dist = 0;

	//算法开始
	opened.add(nodes[s]);
	while(!opened.empty()){
		Node* temp = opened.removeFirst();
		//遍历所有相邻顶点
		for(int i = 0; i < n; i++){
			if(map[temp->index][i] != 0 && !closed.exists(nodes[i])){  //  剪枝
				int distance = temp->dist + map[temp->index][i];
				if(distance < nodes[i]->dist){                         ///如果到源点有更小的距离，则更新这个距离
					nodes[i]->dist = distance;
				}
				//添加相邻顶点到开放队列中
				if(!opened.exists(nodes[i])){
					opened.add(nodes[i]);
				}

			}
		}

		closed.add(temp);
	}

	return nodes[d]->dist;
}


int main(){

	int map[MAX_V][MAX_V] = {0};  // 0 认为不可达

	map[0][1] = 2;
	map[0][2] = 3;
	map[0][3] = 4;
	map[1][2] = 3;
	map[1][5] = 2;
	map[1][4] = 7;
	map[2][6] = 2;
	map[2][5] = 9;
	map[3][6] = 2;
	map[4][7] = 10;
	map[4][8] = 10;
	map[5][6] = 1;
	map[5][8] = 3;
	map[6][8] = 5;
	map[6][9] = 1;
	map[7][10] = 10;
	map[8][10] = 10;
	map[9][8] = 2;
	map[9][10] = 2;

	cout << "min distance:" << Dijkstra(map, 11, 0, 10);

	return 0;
}
